from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QFrame, QLabel, QTextEdit
from PyQt5.QtCore import pyqtSignal, Qt

class StepsWidget(QWidget):
    stepClicked = pyqtSignal(int)  # 定义信号以传递被点击的步骤索引

    def __init__(self, steps, descriptions, parent=None):
        super().__init__(parent)
        self.steps = steps
        self.descriptions = descriptions
        self.current_step = 0
        self.selected_step = 0  # 确保初始化 selected_step
        self.step_status = ['not_started'] * len(steps)  # 初始化所有步骤为未开始
        self.step_details = {i: "" for i in range(len(steps))}  # 初始化步骤详情为空字符串
        self.initUI()

    def initUI(self):
        layout = QVBoxLayout(self)

        # 使用 QHBoxLayout 来排列步骤
        self.step_layout = QHBoxLayout()  # 将 step_layout 设为实例变量
        for i, step in enumerate(self.steps):
            # 步骤指示器
            step_indicator = QPushButton(self)  # 使用QLabel作为步骤节点
            step_indicator.setFixedSize(40, 40)  # 设置圆形大小
            step_indicator.setStyleSheet("border-radius: 20px; padding: 0;")  # 圆形样式
            # step_indicator.setAlignment(Qt.AlignCenter)

            # 绑定步骤点击事件
            step_indicator.clicked.connect(lambda checked, index=i: self.onStepClicked(index))

            self.step_layout.addWidget(step_indicator)

            # 步骤描述
            desc_label = QLabel(self.descriptions[i], self)
            desc_label.setStyleSheet("font-size: 12px; color: #666666; margin-left: 1px; margin-right: 1px;")
            self.step_layout.addWidget(desc_label)

            # 根据状态设置节点的样式与内容
            try:
                self.updateStepIndicator(i)  # 初始化时更新节点样式
            except Exception as e:
                print(f"Error initializing step indicator for step {i}: {e}")

            # 添加连接线
            if i < len(self.steps) - 1:
                line = QFrame(self)  # 使用QFrame作为连接线
                line.setFrameShape(QFrame.HLine)  # 设置为水平线
                line.setFrameShadow(QFrame.Sunken)  
                line.setStyleSheet("background-color: #cccccc; height: 2px; margin: 0;")  # 设置线的样式
                # 让线的长度自适应
                line.setFixedWidth(self.width() / (len(self.steps) - 1))
                self.step_layout.addWidget(line)

        layout.addLayout(self.step_layout)  # 添加 step_layout 到主布局
        
        # 添加详情显示区域
        self.detail_area = QTextEdit(self)
        self.detail_area.setReadOnly(True)
        self.detail_area.setMinimumHeight(150)
        self.detail_area.setStyleSheet("background-color: #f5f5f5; border: 1px solid #ddd; padding: 8px;")
        self.detail_area.setPlaceholderText("点击步骤查看详细测试信息")
        layout.addWidget(self.detail_area)

    def onStepClicked(self, step_index):
        """当步骤节点被点击时发射信号并显示详情"""
        self.selected_step = step_index
        self.stepClicked.emit(step_index)  # 发射信号，传递步骤索引
        self.showStepDetail(step_index)  # 显示步骤详情
        
        # 高亮显示选中的步骤
        for i in range(len(self.steps)):
            try:
                indicator = self.step_layout.itemAt(i * 3).widget()
                if indicator:
                    # 保持原有状态样式，但为选中的添加边框
                    if i == step_index:
                        current_style = indicator.styleSheet()
                        if "border: 2px solid #1890ff" not in current_style:
                            indicator.setStyleSheet(current_style + "; border: 2px solid #1890ff;")
                    else:
                        current_style = indicator.styleSheet()
                        indicator.setStyleSheet(current_style.replace("; border: 2px solid #1890ff", ""))
            except Exception as e:
                print(f"Error highlighting step {i}: {e}")

    def showStepDetail(self, step_index):
        """显示步骤详情"""
        try:
            if 0 <= step_index < len(self.steps):
                self.selected_step = step_index
                
                # 清空详情区域
                self.detail_area.clear()
                
                # 显示步骤标题
                title = f"<h3>{self.steps[step_index]}</h3>"
                
                # 显示步骤状态
                status_text = ""
                if self.step_status[step_index] == 'finished':
                    status_text = '<p style="color: #4CAF50;"><b>状态: 已完成</b></p>'
                elif self.step_status[step_index] == 'failed':
                    status_text = '<p style="color: #ff4d4f;"><b>状态: 失败</b></p>'
                elif self.step_status[step_index] == 'in_progress':
                    status_text = '<p style="color: #007BFF;"><b>状态: 进行中</b></p>'
                else:
                    status_text = '<p style="color: #666666;"><b>状态: 未开始</b></p>'
                
                # 显示步骤详情
                detail_content = self.step_details[step_index] if self.step_details[step_index] else "暂无详细信息"
                
                # 组合HTML内容
                html_content = f"{title}{status_text}<div>{detail_content}</div>"
                self.detail_area.setHtml(html_content)
        except Exception as e:
            print(f"显示步骤 {step_index} 的详情时出错: {e}")

    def setCurrentStep(self, step_index):
        """设置当前步骤"""
        try:
            if 0 <= step_index < len(self.steps):
                self.current_step = step_index
                self.updateStepIndicator(self.current_step)  # 更新当前步骤节点样式
                self.update()  # 触发重绘
            else:
                raise ValueError(f"Invalid step index: {step_index}. Step index must be between 0 and {len(self.steps) - 1}.")
        except Exception as e:
            print(f"Error setting current step to {step_index}: {e}")

    def updateStepStatus(self, step_index, status):
        """更新步骤状态"""
        try:
            if 0 <= step_index < len(self.steps):
                self.step_status[step_index] = status
                self.updateStepIndicator(step_index)  # 更新指定步骤节点样式
                # 如果当前正在显示该步骤的详情，则更新详情显示
                if self.selected_step == step_index:
                    self.showStepDetail(step_index)
                self.update()  # 触发重绘
            else:
                raise ValueError(f"Invalid step index: {step_index}. Step index must be between 0 and {len(self.steps) - 1}.")
        except Exception as e:
            print(f"Error updating step status for step {step_index}: {e}")
            
    def updateStepDetail(self, step_index, detail_text):
        """更新步骤的详细信息"""
        try:
            if 0 <= step_index < len(self.steps):
                self.step_details[step_index] = detail_text
                # 如果当前正在显示该步骤的详情，则更新详情显示
                if self.selected_step == step_index:
                    self.showStepDetail(step_index)
            else:
                raise ValueError(f"Invalid step index: {step_index}. Step index must be between 0 and {len(self.steps) - 1}.")
        except Exception as e:
            print(f"Error updating step detail for step {step_index}: {e}")
            
    def addStepDetail(self, step_index, detail_text):
        """添加步骤详情
        
        Args:
            step_index (int): 步骤索引
            detail_text (str): 详情文本
        """
        try:
            if 0 <= step_index < len(self.steps):
                # 初始化 step_details 字典（如果不存在）
                if not hasattr(self, 'step_details'):
                    self.step_details = {i: "" for i in range(len(self.steps))}
                
                # 将详情文本添加到对应步骤，使用字符串拼接而不是 append
                if self.step_details[step_index]:
                    self.step_details[step_index] += f"<br>{detail_text}"
                else:
                    self.step_details[step_index] = detail_text
                
                # 如果当前正在显示该步骤的详情，则刷新显示
                if hasattr(self, 'selected_step') and self.selected_step == step_index:
                    self.showStepDetail(step_index)
        except Exception as e:
            print(f"添加步骤 {step_index} 的详情时出错: {e}")

    def updateStepIndicator(self, step_index):
        try:
            # 步骤节点的下标从0开始，间隔为 3
            step_indicator = self.step_layout.itemAt(step_index * 3).widget()  # Get the step indicator
            if step_indicator is not None:
                base_style = "border-radius: 20px; padding: 0;"
                # 如果是选中的步骤，添加边框样式
                if step_index == self.selected_step:
                    base_style += "; border: 2px solid #1890ff;"
                    
                if self.step_status[step_index] == 'finished':
                    step_indicator.setStyleSheet(f"background-color: #4CAF50; color: white; {base_style}")  # Green
                    step_indicator.setText("☑️")  # Check mark
                elif self.step_status[step_index] == 'failed':
                    step_indicator.setStyleSheet(f"background-color: #ff4d4f; color: white; {base_style}")  # Red
                    step_indicator.setText("✖️")  # Cross mark
                elif self.step_status[step_index] == "in_progress":
                    step_indicator.setStyleSheet(
                        f"background-color: #007BFF; color: white; {base_style}"
                    )
                    step_indicator.setText(f"{step_index}")
                    # 修复字体设置：先获取字体对象再设置粗体
                    font = step_indicator.font()
                    font.setBold(True)
                    step_indicator.setFont(font)  # 正确传递QFont对象
                else:  # Not started
                    step_indicator.setStyleSheet(f"background-color: #cccccc; color: black; {base_style}")  # Gray
                    step_indicator.setText(f"{step_index}")  
            else:
                print(f"Error: No widget found at index {step_index * 3} in step_layout")
        except Exception as e:
            print(f"Error updating step indicator for step {step_index}: {e}")